package com.wei.czz.common.tool;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.wei.czz.common.constant.Constant;
import com.wei.czz.common.enums.ResultEnum;
import lombok.Getter;
import lombok.Setter;
import org.slf4j.MDC;

/**
 * Created by IntelliJ IDEA.
 *
 * @author wei
 * date: 2022-03-18 16:49:28
 * className: Result http请求结果封装类
 * version: 1.0
 * description:
 *  `@JsonInclude(JsonInclude.Include.NON_EMPTY)`：接口返回对象时，如果某个字段值为空，序列化不操作该字段
 */
@Getter
@Setter
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Result<T> extends BaseEntity {

    /**
     * 请求响应状态码
     */
    private Integer code;

    /**
     * 请求回复消息
     */
    private String msg;

    /**
     * 请求结果
     * 当值为空时，序列化时放弃序列化本属性
     */
    private T data;

    /**
     * 请求主键
     */
    protected String requestId;

    private Result() {}

    /**
     * 判断是否请求成功
     * @return true-成功 false-失败
     */
    public boolean isSuccess() {
        return ResultEnum.SUCCESS.getCode().equals(code);
    }

    /**
     * 判断是否请求失败
     * @return true-失败 false-成功
     */
    @JsonIgnore
    public boolean isFail() {
        return !isSuccess();
    }

    public static <T> Result<T> success(T data) {
        Result<T> result = success();
        result.data = data;
        return result;
    }

    public static <T> Result<T> success() {
        return getResult(ResultEnum.SUCCESS);
    }

    public static <T> Result<T> fail() {
        return fail(ResultEnum.SERVICE_FAIL.getCode());
    }

    public static <T> Result<T> fail(Integer code) {
        return getResult(code, ResultEnum.SERVICE_FAIL.getMsg());
    }

    public static <T> Result<T> fail(String msg) {
        return getResult(ResultEnum.SERVICE_FAIL.getCode(), msg);
    }

    /**
     * 封装接口请求参数错误反馈信息
     * @return 结果对象
     */
    public static <T> Result<T> paramFail() {
        return getResult(ResultEnum.PARAM_FAIL);
    }

    /**
     * 封装接口分页参数错误反馈信息
     * @return 结果对象
     */
    public static <T> Result<T> pageFail() {
        return getResult(ResultEnum.PAGE_FAIL);
    }

    /**
     * 批量处理数量超过设定阈值，返回错误数据
     * @return 结果对象
     */
    public static <T> Result<T> batchFail() {
        return getResult(ResultEnum.BATCH_FAIL);
    }

    /**
     * 由客户端请求数据导致操作失败，返回错误数据
     * @param msg 提示消息
     * @return 结果对象
     */
    public static <T> Result<T> clientFail(String msg) {
        return getResult(ResultEnum.REQUEST_FAIL.getCode(), msg);
    }

    /**
     * 获取请求结果对象
     * @param code 状态码
     * @param msg  提示消息
     * @return 请求结果对象
     * @param <T> 泛型
     */
    public static <T> Result<T> getResult(Integer code, String msg) {
        return getResult(code, msg, null);
    }

    /**
     * 获取请求结果对象
     * @param code 状态码
     * @param msg  提示消息
     * @param data 返回数据
     * @return 请求结果对象
     * @param <T> 泛型
     */
    public static <T> Result<T> getResult(Integer code, String msg, T data) {
        Result<T> result = new Result<>();
        result.code = code;
        result.msg = msg;
        result.data = data;
        result.requestId = MDC.get(Constant.TRACE_ID);
        return result;
    }

    /**
     * 获取请求结果对象
     * @param resultEnum 请求结果枚举对象
     * @return 请求结果对象
     * @param <T> 泛型
     */
    public static <T> Result<T> getResult(ResultEnum resultEnum) {
        return getResult(resultEnum.getCode(), resultEnum.getMsg(), null);
    }
}
